#include "qtc_cppcheck.h"
#include "qtc_cppcheckconstants.h"

#include <coreplugin/icore.h>
#include <coreplugin/icontext.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/coreconstants.h>

#include <coreplugin/idocument.h>
#include <coreplugin/editormanager/editormanager.h>

#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectnodes.h>
#include <projectexplorer/project.h>
#include <projectexplorer/taskhub.h>
#include <projectexplorer/projecttree.h>

#include <QAction>
#include <QMessageBox>
#include <QMainWindow>
#include <QMenu>

#include "optionpage.h"
#include "cdlgcheckproject.h"
#include "worker_check.h"

namespace qtc_cppcheck {
namespace Internal {

qtc_cppcheckPlugin::qtc_cppcheckPlugin()
{
    // Create your members
    m_worker_check = new Worker_Check;
}

qtc_cppcheckPlugin::~qtc_cppcheckPlugin()
{
    // Unregister objects from the plugin manager's object pool
    // Delete members
    m_worker_check->stopCheck();
    delete m_worker_check;
}

bool qtc_cppcheckPlugin::initialize(const QStringList &arguments, QString *errorString)
{
    // Register objects in the plugin manager's object pool
    // Load settings
    // Add actions to menus
    // Connect to other plugins' signals
    // In the initialize function, a plugin can be sure that the plugins it
    // depends on have initialized their members.

    Q_UNUSED(arguments)
    Q_UNUSED(errorString)

    auto actionNode = new QAction(QString("使用cppcheck检查"), this);
    Core::Command *cmdNode = Core::ActionManager::registerAction(actionNode, Constants::ACTION_NODE_ID,
                                                             Core::Context(Core::Constants::C_EDIT_MODE));
    connect(actionNode, &QAction::triggered, this, &qtc_cppcheckPlugin::triggerActionNode);

    Core::ActionContainer *tempMenu = Core::ActionManager::actionContainer(ProjectExplorer::Constants::M_FILECONTEXT);
    if(tempMenu != NULL)
    {
        tempMenu->addAction(cmdNode);
    }
    tempMenu = Core::ActionManager::actionContainer(ProjectExplorer::Constants::M_FOLDERCONTEXT);
    if(tempMenu != NULL)
    {
        tempMenu->addAction(cmdNode);
    }
    tempMenu = Core::ActionManager::actionContainer(ProjectExplorer::Constants::M_PROJECTCONTEXT);
    if(tempMenu != NULL)
    {
        tempMenu->addAction(cmdNode);
    }
    tempMenu = Core::ActionManager::actionContainer(ProjectExplorer::Constants::M_SUBPROJECTCONTEXT);
    if(tempMenu != NULL)
    {
        tempMenu->addAction(cmdNode);
    }
    ProjectExplorer::TaskHub::addCategory(Constants::TASK_CATEGORY_ID,
                                          QString(Constants::TASK_CATEGORY_NAME));

    QAction *actionFile = new QAction(QString("检查当前文件"), this);
    Core::Command *cmdFile = Core::ActionManager::registerAction(actionFile, Constants::ACTION_FILE_ID,
                             Core::Context(Core::Constants::C_GLOBAL));
    cmdFile->setDefaultKeySequence(QKeySequence(("Alt+F9")));
    connect(actionFile, &QAction::triggered, this, &qtc_cppcheckPlugin::triggerActionFile);

    QAction *actionProject = new QAction(QString("检查当前项目"), this);
    Core::Command *cmdProject = Core::ActionManager::registerAction(actionProject, Constants::ACTION_PROJECT_ID,
                                Core::Context(Core::Constants::C_GLOBAL));
    connect(actionProject, &QAction::triggered, this, &qtc_cppcheckPlugin::triggerActionProject);

    Core::ActionContainer *menu = Core::ActionManager::createMenu(Constants::MENU_ID);
    menu->menu()->setTitle(QString("CppCheck检查"));
    menu->addAction(cmdFile);
    menu->addAction(cmdProject);
    Core::ActionManager::actionContainer(Core::Constants::M_TOOLS)->addMenu(menu);

    m_optionPage = new OptionPage(this);

    return true;
}

void qtc_cppcheckPlugin::extensionsInitialized()
{
    // Retrieve objects from the plugin manager's object pool
    // In the extensionsInitialized function, a plugin can be sure that all
    // plugins that depend on it are completely initialized.
}

ExtensionSystem::IPlugin::ShutdownFlag qtc_cppcheckPlugin::aboutToShutdown()
{
    // Save settings
    // Disconnect from signals that are not needed during shutdown
    // Hide UI (if you add UI that is not in the main window directly)
    return SynchronousShutdown;
}

void qtc_cppcheckPlugin::triggerActionNode()
{
    ProjectExplorer::Node* node = ProjectExplorer::ProjectTree::currentNode();
    if (node == NULL)
    {
        return;
    }
    m_worker_check->checkNode(node);
}

void qtc_cppcheckPlugin::triggerActionFile()
{
    Core::IDocument* document = Core::EditorManager::currentDocument();
    if (document == NULL)
    {
        return;
    }
    m_worker_check->checkFiles(QStringList() << document->filePath().toString());
}

void qtc_cppcheckPlugin::triggerActionProject()
{
    CDlgCheckProject dlg;
    dlg.exec();
}


} // namespace Internal
} // namespace qtc_cppcheck
